/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.npmpackagepatch;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

public class FileOperation {
    private static final String ENCODING = "UTF-8";
    private static final String UTF8_BOM_HEADER = "\ufeff";

    /**
     * Read file content as string
     *
     * @param path the full file path
     * @return the string
     * @description 根据文件的完整路径，读取文件内容（UTF-8编码）
     */
    public static String readAsString(String path) {
        File file = new File(path);
        long fileLength = file.length();
        byte[] fileContent = new byte[(int) fileLength];
        try (FileInputStream in = new FileInputStream(file);) {
            in.read(fileContent);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("readAsString failed", e);
        }

        try {
            // 判断有没有utf-8 bom头， 有则去除。
            String fileContents = new String(fileContent, ENCODING);
            if (fileContents.startsWith(UTF8_BOM_HEADER)) {
                fileContents = fileContents.substring(1);
            }
            return fileContents;
        } catch (UnsupportedEncodingException e) {
            System.err.println("The OS does not support " + ENCODING);
            e.printStackTrace();
            return null;
        }
    }

    public static void copyFile(String sourcePath, String targetPath) {
        try {
            File sourceFile = new File(sourcePath);
            File targetFile = new File(targetPath);
            copyFile(sourceFile, targetFile);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void copyFile(File sourcePath, File targetPath) {
        try {
            if (!sourcePath.exists()) {
                return;
            }
            sourcePath.setExecutable(true);
            sourcePath.setReadable(true);
            sourcePath.setWritable(true);
            Files.copy(sourcePath.toPath(), targetPath.toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 将文本写入指定文件; 如果文件不存在先创建文件，再执行写入操作; 如果文件存在，删除后重新创建并写入。
     *
     * @param fileNameAndPath 目标文件路径
     * @param contents        写入文件的内容
     */
    public static void writeFile(String fileNameAndPath, String contents) {
        // 如果文件路径不存在 那么创建对应的文件目录
        File file = new File(fileNameAndPath);

        File fileParent = file.getParentFile();
        if (!fileParent.exists()) {
            fileParent.mkdirs();
        }

        if (exists(file)) {
            clear(file);
        } else {
            createFile(file);
        }
        // 如果写入的内容为null  那么转换成空字符串写入
        if (contents == null) {
            contents = "";
        }
        updateFile(fileNameAndPath, contents);
    }

    /**
     * 检测文件或目录是否存在
     *
     * @param fileHandler 文件或目录句柄
     * @return
     */
    private static boolean exists(File fileHandler) {
        return fileHandler.exists();
    }

    /**
     * 清空文件中内容
     *
     * @param file 待清空文件句柄
     */
    private static void clear(File file) {
        if (file.exists()) {
            file.setWritable(true);
            file.setReadable(true);
            file.setExecutable(true);
        }

        try (FileWriter fileWriter = new FileWriter(file)) {
            fileWriter.write("");
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建文件
     *
     * @param path 待创建文件路径
     */
    public static void createFile(String path) {
        try {
            File file = new File(path);
            if (!exists(file)) {
                file.createNewFile();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 创建文件
     *
     * @param file 待创建文件句柄
     */
    private static boolean createFile(File file) {
        try {
            file.createNewFile();
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    /**
     * 更新文件
     *
     * @param fullPath
     * @param content
     */
    public static void updateFile(String fullPath, String content) {
        byte[] buffer = content.getBytes(StandardCharsets.UTF_8);
        try (FileOutputStream fos = new FileOutputStream(fullPath, true);) {
            fos.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
